package com.community.sqlapp.service.biz;

import com.community.sqlapp.entity.testCaseTemplate.TestCaseOnesTemplate;
import com.community.sqlapp.entity.testCaseTemplate.TestCaseMeterSphereTemplate;
import com.community.sqlapp.entity.testCasePo.TestCaseInfoPo;
import com.community.sqlapp.entity.testCasePo.TestMeterSphereCasePo;
import com.community.sqlapp.entity.testCasePo.TestOnesCasePo;
import com.community.sqlapp.utils.ExcelUtil;
import com.community.sqlapp.utils.FileExtension;
import com.community.sqlapp.utils.FileUtil;
import org.apache.poi.ss.usermodel.*;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 写入测试用例到Excel类
 */
public class InsetTestCaseToExcel {
    private static Logger logger = LoggerFactory.getLogger(XMindToExcel.class);

    /** MS用例集合 */
    static List<TestMeterSphereCasePo> testCases = new ArrayList<>();

    /** ones用例集合 */
    static List<TestOnesCasePo> testOnesCases = new ArrayList<>();
    /** XMind 原始文件 */
    static File xMindFile;
    /** 用例集合 */
    public static TestCaseInfoPo testCaseInfo = new TestCaseInfoPo();

    /** 输出的测试用例Excel文件 */
    static String excelFilePath;

    /** 导出Excel Style */
    static CellStyle cellStyle = null;

    /***
     * &Desc: xMind 转换 Excel文件
     * @param
     * @return void
     */
    public static void xMindToExcel(String items) {
        // 将xMind转换为zip文件
        File xMindZipFile= FileUtil.transferXMind2Zip(xMindFile);
        // 获取xMind的zip文件路径
        String zipPath = xMindZipFile.getAbsolutePath();
        String descDir =null;
        if(zipPath.endsWith(FileExtension.ZIP)){
            descDir=zipPath.substring(0,zipPath.length() - FileExtension.ZIP.length());
        }
        // 解压ZIP文件 到descDir目录
        try {
            FileUtil.unZipFiles(zipPath, descDir);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        // 获取xMind content.xml文件
        File xmlFile = new File(descDir + "/content.xml");
        // 创建一个SAXReader对象
        SAXReader sax = new SAXReader();
        try{
            // 获取document对象,如果文档无节点，则会抛出Exception提前结束
            Document document = sax.read(xmlFile);
            // 获取xMind根节点
            Element root = document.getRootElement();
            // 从根节点开始遍历解析所有节点, 生成测试用例list
            testCases.clear();
            testOnesCases.clear();
            logger.info("******************解析用例********************");
            parseXMind(root,items);
            logger.info("=====================>用例解析完毕");
        }catch (DocumentException de){
            de.printStackTrace();
            logger.error(de.getMessage());
        }catch (FileNotFoundException nfe){
            nfe.printStackTrace();
            logger.error(nfe.getMessage());
        }

        //删除临时文件夹
        logger.info("******************清理临时文件********************");
        //File temp = new File(xMindZipFile.getParent());
        //FileUtil.deleteDir(temp);
        // list用例写入Excel 统计用例总数、步骤数、验证点数
        logger.info("******************用例写入Excel，统计用例基本信息********************");
        InsetTestCaseToExcel.testCaseWriteToExcel(items);
        logger.info("******************用例转换完毕********************");
    }

    /***
     * &Desc: 解析XMind
     * @param node 指定节点开始解析
     * @return void
     */
    private static void parseXMind(Element node,String items) throws FileNotFoundException {
        // 解析节点
        if (node != null) {
            // 获取root topic信息
            XMindToExcel.dealXMindRootInfo(node);

            // 分支主题
            if("topics".equals(node.getName()) && "attached".equals(node.attributeValue("type"))){
                // 获取所有的topic分支节点
                List<Element> topicList = node.elements("topic");
                // 遍历所有的topic分支节点
                for (Element el: topicList) {
                    Element eMarker = el.element("marker-refs");
                    // 如果是模块 或 用例节点
                    if(eMarker != null){
                        Element eMarkerRef = eMarker.element("marker-ref");
                        String markerIcon = eMarkerRef.attributeValue("marker-id");
                        // 用例
                        if(markerIcon.startsWith("priority")){
                            logger.info("###########当前node为用例:" + el.element("title").getStringValue());
                            if(items.equals("MeterSphere")){
                                TestMeterSphereCasePo testCasePO = XMindToExcel.dealXMindTestMeterSphereCase(el, markerIcon);
                                testCases.add(testCasePO);
                            }if(items.equals("ones")){
                                TestOnesCasePo testOnesCasePo=XMindToExcel.dealXMindTestOnesCase(el, markerIcon);
                                testOnesCases.add(testOnesCasePo);
                            }
                        }
                        // 模块
                        if(markerIcon.startsWith("flag") || markerIcon.startsWith("star")){
                            logger.info("###########当前node为模块:" + el.element("title").getStringValue());
                        }
                    }
                }
            }
        }

        // 递归遍历当前节点所有的子节点
        List<Element> listElement = node.elements();
        // 遍历所有一级子节点
        for (Element e : listElement) {
            // 递归
            parseXMind(e,items);
        }
    }

    /** &Desc: 生成excel文件 */
    public static void setExcelFilePath(String excelFilePath) {
        InsetTestCaseToExcel.excelFilePath = excelFilePath;
    }

    public static void setXMindFile(File xMindFile) {
        InsetTestCaseToExcel.xMindFile = xMindFile;
    }
    /***
     * &Desc: 设置单元格格式
     * @param workbook 工作簿
     * @return void
     */
    private static void setCellStyle(Workbook workbook){
        /** 创建一个样式 */
        cellStyle = workbook.createCellStyle();
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
    }

    /***
     * 修改点：加了传递参数
     * &Desc: test case从list中写入Excel
     * @param
     * @return void
     */
    public static void testCaseWriteToExcel(String items){
        ExcelUtil.createExcel(excelFilePath);
        // 读取Excel文件;
        Workbook workbook = ExcelUtil.readExcel(excelFilePath);
        // 创建一个样式
        setCellStyle(workbook);
        // 获取解析用例的表格
        Sheet caseSheet = workbook.getSheetAt(0);
        //新增代码
        if(items.equals("MeterSphere")){
            // 创建MS模版表头
            TestCaseTypeHeaderSets.setSheetColumnHeader(caseSheet, cellStyle);
        }
        if(items.equals("ones")){
            // 创建ones模版表头
            TestCaseTypeHeaderSets.setSheetOnesColumnHeader(caseSheet, cellStyle);
        }
        // 逐条写入用例 并统计测试步骤验证点数量
        int steps = 0;
        int checkPointers = 0;
        int testCaseRowNum = 1;
        Row testcaseRow = caseSheet.createRow(testCaseRowNum);
        //这里改了代码，包了一层if
        if(items.equals("MeterSphere")){
            //往MS模版写入用例
            for (TestMeterSphereCasePo po: testCases) {
                steps += po.getActions().size();
                checkPointers += po.getResults().size();
                InsetTestCaseToExcel.insertTestCaseToExcel(testcaseRow, po);
                if(testCaseRowNum < testCases.size()){
                    testCaseRowNum ++;
                    testcaseRow = caseSheet.createRow(testCaseRowNum);
                }
            }
            // 统计测试用例、测试步骤、验证点数量
            testCaseInfo.setTestCaseNo(testCases.size());
        }
        if(items.equals("ones")){
            //往ONES模版写入用例
            for (TestOnesCasePo opo: testOnesCases) {
                steps += opo.getActions().size();
                checkPointers += opo.getResults().size();
                InsetTestCaseToExcel.insertOnesTestCaseToExcel(testcaseRow, opo);
                if(testCaseRowNum < testOnesCases.size()){
                    testCaseRowNum ++;
                    testcaseRow = caseSheet.createRow(testCaseRowNum);
                }
            }
            //新增代码
            testCaseInfo.setTestCaseNo(testOnesCases.size());
        }
        testCaseInfo.setTestCaseSteps(steps);
        testCaseInfo.setTestCaseCheckPointers(checkPointers);
        // 关闭文件流
        OutputStream stream = null;
        try {
            stream = new FileOutputStream(excelFilePath);
            workbook.write(stream);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        } finally {
            try {
                stream.close();
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /***
     * &Desc: 测试用例对象 写入到MS模版Excel的指定行
     * @param testcaseRow 写入的Excel sheet 表行
     * @param testCasePO 测试用例对象
     * @return void
     */
    public static void insertTestCaseToExcel(Row testcaseRow, TestMeterSphereCasePo testCasePO){
        /** 所属模块 */
        Cell testCaseCatalogCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.TESTCASECATALOG);
        testCaseCatalogCell.setCellStyle(cellStyle);
        testCaseCatalogCell.setCellValue(testCasePO.getTestCaseCatalog());
        /** 用例名称 */
        Cell testCaseNameCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.TESTCASENAME);
        testCaseNameCell.setCellStyle(cellStyle);
        testCaseNameCell.setCellValue(testCasePO.getTestCaseName());
        /** 前置条件 */
        Cell predicationCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.PREDICATION);
        predicationCell.setCellStyle(cellStyle);
        predicationCell.setCellValue(testCasePO.getPredication());
        /** 步骤描述 */
        Cell actionsCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.ACTIONS);
        actionsCell.setCellStyle(cellStyle);
        List<String> actions = testCasePO.getActions();
        StringBuilder sb = new StringBuilder();
        for(int item=0; item<actions.size(); item++){
            sb.append(actions.get(item));
            if(item < actions.size()-1){
                sb.append("\n");
            }
        }
        actionsCell.setCellValue(sb.toString());
        /** 预期结果 */
        Cell resultsCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.RESULTS);
        resultsCell.setCellStyle(cellStyle);
        List<String> results = testCasePO.getResults();
        sb.setLength(0);
        for(int item=0; item<results.size(); item++){
            sb.append(results.get(item));
            if(item < results.size()-1){
                sb.append("\n");
            }
        }
        resultsCell.setCellValue(sb.toString());
        /** 标签 */
        Cell testCaseTypeCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.TESTCASETYPE);
        testCaseTypeCell.setCellStyle(cellStyle);
        testCaseTypeCell.setCellValue(testCasePO.getTestCaseType());
        /** 用例等级 */
        Cell priorityCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.PRIORITY);
        priorityCell.setCellStyle(cellStyle);
        priorityCell.setCellValue(testCasePO.getPriority());
        /** 备注 */
        Cell detailCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.DETAILS);
        detailCell.setCellStyle(cellStyle);
        detailCell.setCellValue(testCasePO.getDetails());
        /** 编辑模式 */
        Cell uadateModelCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.UPDATEMODELS);
        uadateModelCell.setCellStyle(cellStyle);
        uadateModelCell.setCellValue(testCasePO.getUpdateModels());
        /** 用例状态 */
        Cell caseStatusCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.CASESTATUS);
        caseStatusCell.setCellStyle(cellStyle);
        caseStatusCell.setCellValue(testCasePO.getCaseStatus());
        /** 责任人 */
        Cell caseUsersCell = testcaseRow.createCell(TestCaseMeterSphereTemplate.CASEUSERS);
        caseUsersCell.setCellStyle(cellStyle);
        caseUsersCell.setCellValue(testCasePO.getCaseUsers());
    }

    /**
     * &Desc: 测试用例对象 写入到ones模版Excel的指定行
     * @param testOnesCaseRow 写入的Excel sheet 表行
     * @param testOnesCasePo 测试用例对象
     */
    public static void insertOnesTestCaseToExcel(Row testOnesCaseRow, TestOnesCasePo testOnesCasePo) {
        /** 一级模块 */
        Cell testCaseCatalogCell_1 = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASECATALOG_1);
        testCaseCatalogCell_1.setCellStyle(cellStyle);
        testCaseCatalogCell_1.setCellValue(testOnesCasePo.getTestCaseCatalog_1());
        /** 二级模块 */
        Cell testCaseCatalogCell_2 = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASECATALOG_2);
        testCaseCatalogCell_2.setCellStyle(cellStyle);
        testCaseCatalogCell_2.setCellValue(testOnesCasePo.getTestCaseCatalog_2());
        /** 三级模块 */
        Cell testCaseCatalogCell_3 = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASECATALOG_3);
        testCaseCatalogCell_3.setCellStyle(cellStyle);
        testCaseCatalogCell_3.setCellValue(testOnesCasePo.getTestCaseCatalog_3());
        /** 四级模块 */
        Cell testCaseCatalogCell_4 = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASECATALOG_4);
        testCaseCatalogCell_4.setCellStyle(cellStyle);
        testCaseCatalogCell_4.setCellValue(testOnesCasePo.getTestCaseCatalog_4());
        /** 五级模块 */
        Cell testCaseCatalogCell_5 = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASECATALOG_5);
        testCaseCatalogCell_5.setCellStyle(cellStyle);
        testCaseCatalogCell_5.setCellValue(testOnesCasePo.getTestCaseCatalog_5());
        /** 六级模块 */
        Cell testCaseCatalogCell_6 = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASECATALOG_6);
        testCaseCatalogCell_6.setCellStyle(cellStyle);
        testCaseCatalogCell_6.setCellValue(testOnesCasePo.getTestCaseCatalog_6());
        /** 用例名称 */
        Cell testCaseNameCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASENAME);
        testCaseNameCell.setCellStyle(cellStyle);
        testCaseNameCell.setCellValue(testOnesCasePo.getTestCaseName());
        /** 前置条件 */
        Cell predicationCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.PREDICATION);
        predicationCell.setCellStyle(cellStyle);
        predicationCell.setCellValue(testOnesCasePo.getPredication());
        /** 步骤描述 */
        Cell actionsCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.ACTIONS);
        actionsCell.setCellStyle(cellStyle);
        List<String> actions = testOnesCasePo.getActions();
        StringBuilder sb = new StringBuilder();
        for(int item=0; item<actions.size(); item++){
            sb.append(actions.get(item));
            if(item < actions.size()-1){
                sb.append("\n");
            }
        }
        actionsCell.setCellValue(sb.toString());
        /** 预期结果 */
        Cell resultsCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.RESULTS);
        resultsCell.setCellStyle(cellStyle);
        List<String> results = testOnesCasePo.getResults();
        sb.setLength(0);
        for(int item=0; item<results.size(); item++){
            sb.append(results.get(item));
            if(item < results.size()-1){
                sb.append("\n");
            }
        }
        resultsCell.setCellValue(sb.toString());
        /** 用例类型 */
        Cell testCaseTypeCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.TESTCASETYPE);
        testCaseTypeCell.setCellStyle(cellStyle);
        testCaseTypeCell.setCellValue(testOnesCasePo.getTestCaseType());
        /** 优先级 */
        Cell priorityCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.PRIORITY);
        priorityCell.setCellStyle(cellStyle);
        priorityCell.setCellValue(testOnesCasePo.getPriority());
        /** 备注 */
        Cell detailCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.DETAILS);
        detailCell.setCellStyle(cellStyle);
        detailCell.setCellValue(testOnesCasePo.getCaseDetails());
        /** 责任人 */
        Cell caseUsersCell = testOnesCaseRow.createCell(TestCaseOnesTemplate.CASEUSERS);
        caseUsersCell.setCellStyle(cellStyle);
        caseUsersCell.setCellValue(testOnesCasePo.getCaseUsers());
    }
}
